// =============这里主要是axios请求和响应，以及拦截和基本配置的操作
import axios from 'axios'
import JsonBig from 'json-bigint'
import store from '@/store.js'
import router from '@/router.js'
// ======基本信息的配置，公共根地址
// ===============这里用的统一配置的方法,,,对象进行多项配置
const instance = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/',
  // `transformResponse` 在传递给 then/catch 前，允许修改响应数据
  // ====解决最大安全值的问题
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理
    try {
      return JsonBig.parse(data)
    } catch (e) {
      return data
    }
  }]
})
// ==============================这里实现拦截
// ====请求拦截，并且给headers里加上token------设置header
instance.interceptors.request.use((config) => {
  const it = store.state.auth.token
  if (it) {
    config.headers.Authorization = `Bearer ${store.state.auth.token}`
  }
  // =========一定要记得返回这个config配置属性啊，对象
  return config
}, (error) => {
  // 对请求错误做些什么
  return Promise.reject(error)
})
// ======================响应拦截器主要是判断token是否有效，有一点不同的是，失效后可以在刷新，有效期是14天
// 添加响应拦截器
instance.interceptors.response.use((res) => {
  // 对响应数据做点什么  && 前边满足运行后边 || 前边满足执行前边
  return res.data && res.data.data
}, async (err) => {
  // 对响应错误做点什么
  // 1.响应错误来到这里，看是不是401的错误
  if (err.response && err.response.status === 401) {
    // ============如果不存在token或者refresh，跳到login登录界面,但是一点重要的是要有回挑，要记住失效前的要访问的页面的地址

    if (!store.state.auth.token || !store.state.auth.refresh_token) {
      // ======================这里是难点：新的地址跳转的对象表达方式
      // 3.最后还要把未成功的请求继续发出，得出正确的响应

      return router.push({ path: '/login', query: { redirect: router.currentRoute.path } })
    }

    // 2.401错误，token存在，token失效了的话刷新token，设置新的token，更改，本地和user的token
    // =====这时候就体现出了封装instance函数的作用了。
    try {
      const { data: { data } } = await axios({
        url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',
        method: 'put',
        headers: { Authorization: `Bearer ${store.state.auth.refresh_token}` }
      })
      store.commit('changeUser', {
        token: data.token,
        refresh_token: store.state.auth.refresh_token
      })
      return instance(err.config)
    } catch (e) {
      store.commit('delUser')
      return router.push({ path: '/login', query: { redirect: router.currentRoute.path } })
    }
  }
  return Promise.reject(err)
})
// 对响应错误做点什么
// =======难点在这里最后导出一个可以调用的函数
// ========是把axios的api接口的调用封装成了一个函数，比较方便了，而且导出要记得 啊

export default (url, method, data) => {
  // ====把它们三个传过来的参数进行合并，进行数据的请求发送
  const config = {
    url,
    method,
    // ================重点data
    [method.toLowerCase() === 'get' ? 'params' : 'data']: data

  }
  return instance(config)
}
